package com.antrain.core;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.antrain.utils.AnnotationUtil;
import com.antrain.utils.Dom4jUtil;
import com.antrain.utils.JDBCUtil;

import org.dom4j.Document;

/**
 * 用来解析并封装框架的核心配置文件的数据
 */
public class ORMConfig {
    private static final String XML_NAME = "minORM.cfg.xml";
    // 类路径
    private static String classpath;
    // 核心配置文件
    private static File cfgFile;
    // <property> 标签中的数据
    private static Map<String, String> propConfig;
    // 映射配置文件路径
    private static Set<String> mappingSet;
    // 实体类
    private static Set<String> entitySet;
    // 映射信息
    private static List<Mapper> mapperList;

    public static List<Mapper> geMapperList(){
        return mapperList;
    }

    static {
        // 1.1 得到类路径
        classpath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        // 1.2 针对中文路径进行转码
        try {
            URLDecoder.decode(classpath, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(classpath);
        // 2 得到和谐配置文件
        cfgFile = new File(classpath + XML_NAME);
        if (cfgFile.exists()) {
            // 3 得到核心配置文件的属性
            Document document = Dom4jUtil.getXMLByFilePath(cfgFile.getPath());
            propConfig = Dom4jUtil.elements2Map(document, "property", "name");
            mappingSet = Dom4jUtil.elements2Set(document, "mapping", "resource");
            entitySet = Dom4jUtil.elements2Set(document, "entity", "package");
        } else {
            throw new RuntimeException("未在类路径下找到核心配置文件" + XML_NAME);
        }
    }

  

    @SuppressWarnings("rawtypes")
    private void getMapping() {
        mapperList = new ArrayList<>();
        // 1. 解析xxx.mapper.xml 拿到映射数据
        Document document = null;
        for (String xmlPath : mappingSet) {
            document = Dom4jUtil.getXMLByFilePath(classpath + xmlPath);
            String className = Dom4jUtil.getPropValue(document, "class", "name");
            String tableName = Dom4jUtil.getPropValue(document, "class", "table");
            Map<String, String> idMapper = Dom4jUtil.elementsId2Map(document);
            Map<String, String> propMapper = Dom4jUtil.elements2Map(document);
            mapperList.add(new Mapper(className, tableName, idMapper, propMapper));
        }

        // 2 解析实体类中的注解拿到映射数据
        for (String packagePath : entitySet) {
            Set<String> names = AnnotationUtil.getClassNameByPacking(packagePath);
            for (String name : names) {
                try {
                    Class clz = Class.forName(name);
                    String className = AnnotationUtil.getClassName(clz);
                    String tableName = AnnotationUtil.getTableName(clz);
                    Map<String, String> idMapper = AnnotationUtil.getIdMapper(clz);
                    Map<String, String> propMapper = AnnotationUtil.getPropMapping(clz);
                    mapperList.add(new Mapper(className, tableName, idMapper, propMapper));
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public ORMSession bulid(){
        // 1 初始化数据连接
        JDBCUtil.init(propConfig);
        // 2 得到映射数据
        getMapping();
        // 3 创建 ORMSession对象
        return new ORMSession();

    }

}